﻿using System.Collections.Generic;
using System.Linq;
using Engine;
using Engine.Graphics;
using Game;
using Mekiasm.Common;

namespace Mekiasm
{
    public class AnimateModelItem : ComplexModelItem
    {

        public Dictionary<int, List<ModelItem[]>> Frames;
        public int MaxFrame;
        public string[] RotateMeshes;

        public AnimateModelItem(ModelItem[] modelItems, string[] rotateMeshes, int MaxFrame, string modelName, string n) : base(modelItems, modelName, n)
        {
            Frames = new Dictionary<int, List<ModelItem[]>>();
            RotateMeshes = rotateMeshes;
            this.MaxFrame = MaxFrame;
            InitAllFrame();
        }
        public void InitAllFrame()
        {
            Frames.Clear();
            ModelItem[] modelItems = ModelItems;
            for (int z = 0; z < 4; z++)
            {//旋转
                List<ModelItem[]> BoneFrames = new List<ModelItem[]>();
                for (int i = 0; i < modelItems.Length; i++)
                {//组件
                    ModelItem[] models = new ModelItem[MaxFrame];
                    for (int j = 0; j < MaxFrame; j++)
                    {//帧
                        models[j] = new ModelItem(modelItems[i].meshName, modelItems[i].textureName);
                        models[j].Load(model, modelItems[i].Texture2D);
                        if (RotateMeshes.Where(p => p == modelItems[i].meshName).FirstOrDefault() != null)
                        {
                            models[j].Transform(model, Matrix.CreateRotationX(j * MathUtils.PI / MaxFrame * 2) * Matrix.CreateRotationY(MathUtils.PI * z / 2));
                        }
                        else
                        {
                            models[j].Transform(model, Matrix.CreateRotationY(MathUtils.PI * z / 2));
                        }
                    }
                    BoneFrames.Add(models);
                }
                Frames.Add(z, BoneFrames);
            }
        }
        public override void DrawBlock(PrimitivesRenderer3D primitivesRenderer, int value, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
        {
            int Frame = Time.FrameIndex % MaxFrame;
            List<ModelItem[]> modelItems = Frames[0];
            for (int i = 0; i < modelItems.Count; i++)
            {
                BlocksManager.DrawMeshBlock(primitivesRenderer, modelItems[i][Frame].TransformedBlockMesh, modelItems[i][Frame].Texture2D, Color.White, size * IconScale, ref matrix, environmentData);
            }
        }
        public override void OnBlockAdded(SubsystemBlockBehavior blockBehavior, int value, int oldValue, int x, int y, int z)
        {
        }
        public override void OnBlockRemoved(SubsystemBlockBehavior blockBehavior, int value, int newValue, int x, int y, int z)
        {
        }
        public override void OnBlockGenerated(int value, int x, int y, int z, bool isLoaded)
        {
        }
        public override void GenerateTerrainVertices(Block block, BlockGeometryGenerator generator, TerrainGeometry geometry, int value, int x, int y, int z)
        {
        }
        public override BoundingBox[] GetCustomCollisionBoxes(SubsystemTerrain terrain, MovingBlock value)
        {
            int rotate = ILibrary.GetDirection(value.Value);
            int NowFrame = ILibrary.getExtraData(value.Value);
            List<BoundingBox> boundingBoxes = new List<BoundingBox>();
            List<ModelItem[]> modelItems = Frames[rotate];
            for (int i = 0; i < modelItems.Count; i++)
            {
                BoundingBox boundingBox = modelItems[i][NowFrame].TransformedBlockMesh.CalculateBoundingBox();
                boundingBoxes.Add(boundingBox);
            }
            if (boundingBoxes.Count == 0)
            {
                boundingBoxes.Add(new BoundingBox(Vector3.Zero, Vector3.One));
            }
            return boundingBoxes.ToArray();
        }
        public override BoundingBox[] GetCustomInteractionBoxes(SubsystemTerrain terrain, MovingBlock value)
        {
            return GetCustomCollisionBoxes(terrain, value);
        }

    }
}
